Why DuckDB
原文:https://duckdb.org/docs/why_duckdb
作者:CWI Database Architectures Group
译者:GTrans
校验:李红艳
数据库管理系统(DBMS)已经有很多。但是,没有一种适合所有问题的数据库的系统[1]。所有这些都需要权衡取舍,以便更好地适应特定的用例。DuckDB也不例外。在这里,我们试图解释DuckDB的目标,以及为什么和如何通过技术手段实现这些目标。首先,DuckDB是支持结构化查询语言(SQL)[2]的RDBMS[3]。
快速分析查询
DuckDB旨在支持分析查询工作负载,也称为在线分析处理(OLAP)[4]。这些工作负载的特点是运行时间相对较长的复杂查询,这些查询处理存储数据集的重要部分,例如整个表上的聚合或几个大表之间的联接。预计数据更改的范围也很大,将附加几行,或者同时更改或添加表的大部分。
为了有效地支持此工作负载,减少每个单个值所花费的CPU周期数量至关重要。实现此目标的数据管理技术是矢量化或即时查询执行引擎[6]。DuckDB包含一个列式矢量化查询执行引擎,该查询仍是解释查询,但单个操作(“矢量”)中的大量值将在一个操作中处理。这大大减少了传统系统(如PostgreSQL,MySQL或SQLite)中按顺序处理每一行的开销。向量化查询执行可大大提高OLAP查询的性能。
操作简单
SQLite是世界上部署最广泛的DBMS[6]。安装简单,嵌入式过程内操作是其成功的关键。DuckDB采纳了这些简单性和嵌入式操作的思想。
DuckDB没有外部依赖,无论是用于编译还是在运行时都没有。对于发行版,DuckDB的整个源代码树被编译成两个文件,一个头文件(header)和一个实现文件(动态库),即所谓的“融合”。这极大地简化了其他构建过程中的部署和集成。对于构建,构建DuckDB所需的只是一个可运行的C++11编译器。
对于DuckDB,不需要安装,更新和维护DBMS服务器软件。DuckDB不是作为单独的进程运行,而是完全嵌入到宿主进程中。对于DuckDB针对的分析用例,这具有在数据库之间进行高速数据传输的附加优势。在某些情况下,DuckDB可以处理外部数据而无需复制。例如,DuckDB Python包可以直接对Pandas数据运行查询,而无需导入或复制任何数据。
功能丰富
DuckDB提供了严肃的数据管理功能。带有大量函数库,窗口函数等SQL对复杂查询提供了广泛的支持。DuckDB通过我们的自定义,批量优化的多版本并发控制(MVCC)[7]提供事务保证(ACID属性)。数据可以存储在持久的单文件数据库中。DuckDB支持二级索引,以加快尝试查找单个表条目的查询。
DuckDB已深入集成到Python和R中,以进行有效的交互式数据分析。同时DuckDB提供了Java,C,C ++和其他API。
测试完备
虽然DuckDB由研究小组创建,但它并非旨在成为研究原型。DuckDB旨在成为一个稳定和成熟的数据库系统。
为了促进这种稳定性,使用持续集成[8]对DuckDB进行了严格测试。DuckDB的测试套件目前包含数百万个查询,并且包括根据SQLite,PostgreSQL和MonetDB的测试套件改编而成的查询。在各种各样的平台和编译器上重复测试。将根据完整的测试设置检查每个拉取请求,并且只有在通过后才会合并。
除了这个测试套件,我们还运行各种测试,这些测试会在重负载下对DuckDB施加压力。我们运行TPC-H[9]和TPC-DS[10]基准测试,并在DuckDB上运行各种测试 被许多客户端并行使用。
免费和开源许可证
DuckDB的主要开发人员是荷兰的公务员。我们的工资是从税收中支付的。我们认为,向荷兰或其他地方的任何人免费提供我们的工作成果是我们对社会的责任和义务。这就是为什么在非常宽松的MIT许可证[11]下发布DuckDB的原因。DuckDB是开源的,整个源代码可在GitHub上免费获得。我们邀请任何遵守我们的行为准则[12]的人员提供捐助。
同行评审论文
数据科学的数据管理-面向嵌入式分析(CIDR 2020)[13]
DuckDB:可嵌入的分析数据库(SIGMOD 2019演示)[14]
演示
DuckDB –用于分析的SQLite(视频演示,大约1小时)[15]
DuckDB-可嵌入的分析数据库(视频演示,约15分钟)[16]
DuckDB-可嵌入的分析RDBMS(幻灯片)[17]
其它项目
这是一些我们知道的使用DuckDB的项目。如果您希望在此处添加项目,请在GitHub提交issue。
taxadb:高性能本地分类数据库接口[18]
duckdb.js-DuckDB编译为JavaScript(PoC)[19]
用于DuckDB的R数据帧的SQL[20]
DuckDB conda支持[21]
DuckDB的DBT适配器[22]
DuckDB的newLISP绑定[23]
duckdb_engine-DuckDB的“非常非常基本的” sqlalchemy驱动程序[24]
基于DuckDB的时间序列数据库[25]
使用PHP-FFI集成DuckDB的PHP示例[26]
适用于PostgreSQL的DuckDB外部数据包装器[27]
站在巨人的肩膀上
DuckDB使用了来自各种开源项目的一些组件,并从科学出版物中汲取了灵感。我们对此非常感激。这里是一个概述:
执行引擎:矢量化执行引擎的灵感来自Peter Boncz,Marcin Zukowski和Niels Nes的论文MonetDB/X100:超管道查询执行 [28]。
优化器:DuckDB的优化器从Guido Moerkotte和Thomas的论文动态编程反击[29]中汲取灵感。Neumman以及Thomas Neumann和Alfons Kemper的Unnesting Arbitrary Queries[30]。
并发控制:我们的MVCC实施受到主存储器数据库系统的快速可序列化多版本并发控制[31]的启发。Thomas Neumann,TobiasMühlbauer和Alfons Kemper。
二级索引:DuckDB支持的二级索引,基于论文:主存数据库的ARTful索引[32],由Viktor Leis,Alfons Kemper和Thomas Neumann撰写。
SQL窗口函数:DuckDB的窗口函数实现使用分段树聚合,如Viktor Leis,Kan Kundhikanjana,Alfons Kemper和Thomas Neumann撰写的论文“分析SQL查询中的窗口函数的有效处理”所述。
SQL解析器:我们使用PostgreSQL解析器,该PostgreSQL解析器重新打包为独立库[33]。翻译成我们自己的分析树是受Peloton[34]的启发。
Shell:我们使用SQLite shell[35]与DuckDB一起使用。
正则表达式:DuckDB使用Google的RE2[36]正则表达式引擎。
字符串格式:DuckDB使用fmt[37]字符串格式库。
UTF8:DuckDB使用utf8proc[38]库检查并标准化UTF8。
测试框架:DuckDB使用Catch2[39]单元测试框架。
测试用例:我们使用SQLite的SQL逻辑测试[40]来测试DuckDB。
结果验证:Manuel Rigger[41]使用了他出色的SQLancer[42]工具来验证DuckDB结果的正确性。
查询模糊:我们使用SQLsmith[43]生成随机查询以进行其他测试。
链接
[1] http://cs.brown.edu/research/db/publications/fits_all.pdf
[2] https://en.wikipedia.org/wiki/Relational_database
[3] https://en.wikipedia.org/wiki/SQL
[4] https://en.wikipedia.org/wiki/Online_analytical_processing
[5] https://www.vldb.org/pvldb/vol11/p2209-kersten.pdf
[6] https://www.sqlite.org/mostdeployed.html
[7] https://en.wikipedia.org/wiki/Multiversion_concurrency_control
[8] https://travis-ci.org/cwida/duckdb
[9] http://www.tpc.org/tpch/
[10] http://www.tpc.org/tpcds/
[11] https://en.wikipedia.org/wiki/MIT_License
[12] https://duckdb.org/code_of_conduct
[13] https://hannes.muehleisen.org/CIDR2020-raasveldt-muehleisen-duckdb.pdf
[14] https://hannes.muehleisen.org/SIGMOD2019-demo-duckdb.pdf
[15] https://www.youtube.com/watch?v=PFUZlNQIndo
[16] https://mirrors.dotsrc.org/fosdem/2020/H.2215/duckdb.mp4
[17] https://db.in.tum.de/teaching/ss19/moderndbs/duckdb-tum.pdf
[18] https://cran.r-project.org/package=taxadb
[19] https://github.com/ankoh/duckdb.js
[20] https://github.com/phillc73/duckdf
[21] https://github.com/conda-forge/python-duckdb-feedstock
[22] https://github.com/jwills/dbt-duckdb
[23] https://github.com/luxint/duckdb
[24] https://github.com/Mause/duckdb_engine
[25] https://github.com/berthubert/ducktime
[26] https://github.com/thomasbley/php-duckdb-integration
[27] https://github.com/alitrack/duckdb_fdw
[28] http://cidrdb.org/cidr2005/papers/P19.pdf
[29] https://15721.courses.cs.cmu.edu/spring2020/papers/20-optimizer2/p539-moerkotte.pdf
[30] http://www.btw-2015.de/res/proceedings/Hauptband/Wiss/Neumann-Unnesting_Arbitrary_Querie.pdf
[31] https://db.in.tum.de/~muehlbau/papers/mvcc.pdf
[32] https://db.in.tum.de/~leis/papers/ART.pdf
[33] https://github.com/lfittl/libpg_query
[34] https://pelotondb.io/
[35] https://sqlite.org/cli.html
[36] https://github.com/google/re2
[37] https://github.com/fmtlib/fmt
[38] https://juliastrings.github.io/utf8proc/
[39] https://github.com/catchorg/Catch2
[40] https://www.sqlite.org/sqllogictest/doc/trunk/about.wiki
[41] https://www.manuelrigger.at/
[42] https://github.com/sqlancer/sqlancer
[43] https://github.com/anse1/sqlsmith